package com.marktotop.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.marktotop.entity.business.ReservationRecord;
import com.marktotop.error.SystemCodeEnum;
import com.marktotop.error.SystemException;
import com.marktotop.mapper.ReservationRecordMapper;
import com.marktotop.response.ResultBean;
import com.marktotop.response.ResultCode;
import com.marktotop.service.IReservationRecordService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.marktotop.service.IVaccineDevolutionService;
import com.marktotop.service.IVaccineHistoryService;
import com.marktotop.vo.business.ReservationRecordVO;
import com.marktotop.dto.SiteAndVaccDTO;
import com.marktotop.vo.business.SiteReservationVO;
import com.marktotop.vo.business.VaccineInSiteVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.xml.crypto.Data;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author MarkToTop
 * @since 2021-07-12
 */
@Service
public class ReservationRecordServiceImpl extends ServiceImpl<ReservationRecordMapper, ReservationRecord> implements IReservationRecordService {

    @Autowired
    private ReservationRecordMapper reservationMapper;


    @Autowired
    private IVaccineHistoryService historyService;


    /**
     * 分页展示所有预约记录列表，并进行模糊查询
     *
     * @param pageNum
     * @param pageSize
     * @param reservationRecordVO
     * @return
     * @throws ParseException
     */
    @Override
    public ResultBean findReservationRecordsList(Integer pageNum, Integer pageSize, ReservationRecordVO reservationRecordVO) throws ParseException {
        // 开启分页
        Page<ReservationRecordVO> page = new Page<>(pageNum,pageSize);
        IPage<ReservationRecordVO> reservationRecordByPage = reservationMapper.getReservationRecordByPage(page,reservationRecordVO);
        if (reservationRecordByPage.getRecords().isEmpty()){
            return ResultBean.result(ResultCode.NON_RESULT);
        }
        // String转成Date - 如果预约时间小于当前时间，判断为已过期未接种，由系统人员取消预约
        SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd");
        // 将今天-1
        Calendar c = Calendar.getInstance();
        c.setTime(new Date());
        c.add(Calendar.DATE, -1);
        List<ReservationRecordVO> records = reservationRecordByPage.getRecords();
        for (ReservationRecordVO record : records) {
            Date date = ft.parse(record.getReservationDate());
            // 时间过期
            if (date.compareTo(c.getTime()) < 0){
                // 状态判断 0-3 之外 (小于0 大于3)
                if ( 0 > record.getStates() && record.getStates() > 3){
                    record.setStates(-1);
                }
            }
        }
        return ResultBean.ok().message("获取所有预约疫苗记录信息成功！")
                .data("total",reservationRecordByPage.getTotal())
                .data("reservationRecords",records);
    }


    /**
     * 查询某个接种点下，某个疫苗信息
     *
     * @param siteAndVaccDTO
     * @return
     */
    @Override
    public VaccineInSiteVO findVaccAndSite(SiteAndVaccDTO siteAndVaccDTO) {
        Long siteId = siteAndVaccDTO.getSiteId();
        Long vaccId = siteAndVaccDTO.getVaccId();
        return reservationMapper.getVaccAndSite(siteId,vaccId);
    }


    /**
     * 预约疫苗
     *
     * @param record
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean addReservationRecords(ReservationRecord record) throws SystemException {
        // 拿到要预约的疫苗id 和 与预约接种点id
        Long vaccineId = record.getVaccineId();
        Long siteId = record.getVaccSiteId();
        // 先查询是否已经预约该疫苗的第该针
        ReservationRecord resultRecord = reservationMapper.selectOne(
                new QueryWrapper<ReservationRecord>()
                        .eq("reservator_id",record.getReservatorId())
                        .eq("vaccine_id",vaccineId)
                        .eq("vaccine_needle",record.getVaccineNeedle()));
        if (resultRecord != null){
            throw new SystemException(SystemCodeEnum.PARAMETER_ERROR,"用户已经预约该疫苗的第"+resultRecord.getVaccineNeedle()+"针,不能重复预约!");
        }
        //查询是否有过该疫苗的接种记录 - 疫苗历史
        if (historyService.haveVaccineRecord(record.getReservatorId(), vaccineId)){
            // 有记录，判断当前预约的针数，是否已经注射过
            if (!historyService.getVaccineRecord(record.getReservatorId(), vaccineId,record.getVaccineNeedle())){
                return false;
            }
        }
        // 没有记录，查询该接种点对应疫苗信息
        VaccineInSiteVO vaccAndSite = reservationMapper.getVaccAndSite(siteId, vaccineId);
        if (null == vaccAndSite){
            throw new SystemException(SystemCodeEnum.PARAMETER_ERROR,"没有找到相应接种点的疫苗信息...");
        }
        if ( vaccAndSite.getVaccStock() > 0){
            // 更新中间表库存 -1
            int result = reservationMapper.updateCount(vaccAndSite.getVaccStock() - 1, siteId, vaccineId);
            if (result == 1){
                // 添加预约记录 - 设置二维码
                record.setQrCode("3234234234");
                // 设置预约状态 - 未受理
                record.setStates(0);
                int insert = reservationMapper.insert(record);
                if (insert == 0){
                    return false;
                }
                return true;
            }
            throw new SystemException(SystemCodeEnum.PARAMETER_ERROR,"预约疫苗失败，更新库存失败，请稍后重试...");
        } else {
            throw new SystemException(SystemCodeEnum.PARAMETER_ERROR,"接种点的疫苗数量已经为0,无法预约疫苗...");
        }
    }


    /**
     * 获取单个预约信息
     *
     * @param id
     * @return
     * @throws SystemException
     */
    @Override
    public ReservationRecordVO getOneRecord(Long id) throws SystemException {
        ReservationRecordVO oneReservationRecord = reservationMapper.getOneReservationRecord(id);
        if (null == oneReservationRecord){
            throw new SystemException(SystemCodeEnum.PARAMETER_ERROR,"未找到相关预约信息，请重试...");
        }
        return oneReservationRecord;
    }


    /**
     * 取消预约信息
     *
     * @param id
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean cancelReservation(Long id) throws SystemException {
        // 预约表里是否有记录
        ReservationRecord record = reservationMapper.selectById(id);
        if (null == record){
            throw new SystemException(SystemCodeEnum.PARAMETER_ERROR,"未找到预约记录,请查证...");
        }
        if (record.getStates() == 2){
            throw new SystemException(SystemCodeEnum.PARAMETER_ERROR,"该申请已经进入接种阶段，不能取消！");
        }
        // 根据预约记录 找到疫苗库存
        Integer count = reservationMapper.findStockInfoBySidAndVid(record.getVaccSiteId(), record.getVaccineId());
        // 更加库存数量 库存+1
        int newCount = count + 1;
        if (reservationMapper.updateCount(newCount, record.getVaccSiteId(), record.getVaccineId()) == 0){
            throw new SystemException(SystemCodeEnum.PARAMETER_ERROR,"取消预约记录失败,库存修改失败...");
        }
        // 删除预约记录
        if ( 0== reservationMapper.deleteById(id)){
            throw new SystemException(SystemCodeEnum.PARAMETER_ERROR,"删除预约记录信息失败...");
        }

        return true;
    }


    /**
     * 受理单个预约信息（修改预约状态）
     *
     * @param id
     * @return
     * @throws SystemException
     */
    @Override
    public boolean acceptRecord(Long id) throws SystemException {
        ReservationRecord record = reservationMapper.selectById(id);
        if (null == record){
            throw new SystemException(SystemCodeEnum.PARAMETER_ERROR,"未找到相关预约记录...");
        }
        // 预约状态已经为1
        if (record.getStates() > 0){
            throw new SystemException(SystemCodeEnum.PARAMETER_ERROR,"已受理相关预约记录，不能重复受理...");
        }
        // 更新预约状态 + 1
        record.setStates(record.getStates() + 1);
        if (0 == reservationMapper.updateById(record)){
            return false;
        }
        return true;
    }


    /**
     * 根据预约号id，修改预约状态
     *
     * @param id
     * @param states
     * @return
     */
    @Override
    public boolean updateRecordStates(Long id,Integer states) {
        ReservationRecord reservationRecord = new ReservationRecord();
        reservationRecord.setId(id);
        reservationRecord.setStates(states);
        if (0 == reservationMapper.updateById(reservationRecord)){
            return false;
        }
        return true;
    }


    /**
     * 根据接种点id查找该接种点所有的疫苗预约信息
     *
     * @param id
     * @return
     */
    @Override
    public SiteReservationVO getRecordsBySite(Long id) {
        return reservationMapper.getReservationRecordsBySite(id);
    }


    /**
     * 根据接种人id查询是否有预约记录
     *
     * @param id
     * @return
     */
    @Override
    public boolean haveRecordsByVaccinatorId(Long id) {
        List<ReservationRecord> records = reservationMapper.selectList(
                new QueryWrapper<ReservationRecord>()
                        .eq("reservator_id",id));
        // 没有预约记录，返回false
        if (records.isEmpty()){
            return false;
        }
        return true;
    }

}
